Skip to content

implement expression builders #3761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: development
Choose a base branch
from

Conversation

irina-herciu
Copy link
Contributor

@irina-herciu irina-herciu commented Apr 15, 2025

Add an expression builder for DynamoDB conditional expressions, akin to the Go SDK’s dynamodb/expression package and Boto3’s dynamodb.conditions, to streamline expression creation.

Description

In Document Model add support for fluent ExpressionBuilder similar to the GO SDK. The implementation will follow a design pattern comparable to the Go SDK's expression package, using method chaining to define update actions and condition expressions in a type-safe and readable way.

Create condition expressions examples:

Equal

//existing 
var conditionalExpression = new Expression
{
    ExpressionStatement = "#price = :price",
    ExpressionAttributeNames = { ["#price"] = "Price" },
    ExpressionAttributeValues = { [":price"] = 50 }
};

//build 
var expression = ConditionExpressionBuilder.New().WithName("Price").Equal(50).Build();

And

//existing 
var conditionalExpression = new Expression
                    {
                        ExpressionStatement = "attribute_not_exists(#id) AND #price <> :price",
                        ExpressionAttributeNames = { ["#id"] = "Id", ["#price"] = "Price" },
                        ExpressionAttributeValues = { [":price"] = 500 }
                    };

//build 
var expression = ConditionExpressionBuilder.New().WithName("Id").AttributeExists().
                And(ConditionExpressionBuilder.New().WithName("Price").Equal(50)).Build();

Update actions expression:

Set

//existing 
var updateExpression = new Expression
{
    ExpressionStatement = "SET #garbage = :garbage",
    ExpressionAttributeNames = { ["#garbage"] = "Garbage" },
    ExpressionAttributeValues = { [":garbage"] = "asdf" }
};

//build 
var expression = UpdateExpressionBuilder.New().
    Set(NameBuilder.New("Garbage"), SetValueBuilder.New().WithValue("asdf")).Build();

Set increment

//existing 
var updateExpression = new Expression
{
    ExpressionStatement = "SET #price = #price + :inc",
    ExpressionAttributeNames = { ["#price"] = "Price" },
    ExpressionAttributeValues = { [":inc"] = 1 }
}

//build 
var expression = UpdateExpressionBuilder.New().
    Set(NameBuilder.New("Price"), SetValueBuilder.New().WithName("Price").Plus(1))
    .Build(); 

Motivation and Context

#2602
update the generic parameter documentation for DeleteAsync #2615

Testing

Unit tests added
image

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have read the README document
  • I have added tests to cover my changes
  • All new and existing tests passed

License

  • I confirm that this pull request can be released under the Apache 2 license

expression ConditionBuilder implementation
implement update expression builders and start unit testing
name builder unit tests
@irina-herciu irina-herciu marked this pull request as ready for review April 15, 2025 09:59
@GarrettBeatty
Copy link
Contributor

Thanks for the PR, I will take a look this week at it!

@GarrettBeatty
Copy link
Contributor

GarrettBeatty commented May 1, 2025

code seems fine to me. I started a dry-run on our system to run the tests 71faf318-6389-4e08-a1b0-0375856fe832. I will validate that they all pass and then approve PR

@GarrettBeatty GarrettBeatty requested a review from normj May 1, 2025 19:46
@GarrettBeatty
Copy link
Contributor

71faf318-6389-4e08-a1b0-0375856fe832

the dry run passed/all tests pass

@@ -320,8 +320,10 @@ partial interface IDynamoDBContext
/// The type must be marked up with <see cref="DynamoDBTableAttribute" /> and at least
/// one public field/property with <see cref="DynamoDBHashKeyAttribute" />.
/// </remarks>
/// <typeparam name="T">Type of object.</typeparam>
/// <param name="hashKey">Hash key element of the object to delete.</param>
/// <typeparam name="T">The type representing the item stored in DynamoDB. This must be a modeled type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DynamoDBTableAttribute is optional. There are other ways for the IDynamoDBContext to understand the schema for the POCO besides the attributes. The SDK will default to the name of the type as the table name. Users can also use the TableBuilder to register a schema definition for a type. We don't want to add to the docs to say that attributes are required.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the typeparam summary is updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants